package com.runfast.common.mybatis.plugins;

import com.runfast.common.mybatis.generator.CountByExampleWithPageableElementGenerator;
import com.runfast.common.mybatis.generator.SelectByExampleWithPageableWithBLOBsElementGenerator;
import com.runfast.common.mybatis.generator.SelectByExampleWithPageableWithoutBLOBsElementGenerator;
import org.mybatis.generator.api.*;
import org.mybatis.generator.api.dom.java.*;
import org.mybatis.generator.api.dom.xml.Attribute;
import org.mybatis.generator.api.dom.xml.Document;
import org.mybatis.generator.api.dom.xml.XmlElement;
import org.mybatis.generator.config.Context;
import org.mybatis.generator.config.PropertyRegistry;

import java.util.*;

public class ExtensionPlugin implements Plugin {

    protected Context context;
    protected Properties properties;

    private FullyQualifiedJavaType pageable;
    private Map<FullyQualifiedTable, List<XmlElement>> elementsToAdd;

    public ExtensionPlugin() {
        pageable = new FullyQualifiedJavaType("org.springframework.data.domain.Pageable"); //$NON-NLS-1$
        elementsToAdd = new HashMap<FullyQualifiedTable, List<XmlElement>>();
    }

    @Override
    public void setContext(Context context) {
        this.context = context;
    }

    @Override
    public void setProperties(Properties properties) {
        this.properties = properties;
    }

    @Override
    public void initialized(IntrospectedTable introspectedTable) {

    }

    public boolean validate(List<String> warnings) {
        return true;
    }

    @Override
    public List<GeneratedJavaFile> contextGenerateAdditionalJavaFiles() {
        return null;
    }

    @Override
    public List<GeneratedJavaFile> contextGenerateAdditionalJavaFiles(IntrospectedTable introspectedTable) {
        List<GeneratedJavaFile> answer = new ArrayList<GeneratedJavaFile>();

        CommentGenerator commentGenerator = context.getCommentGenerator();

        FullyQualifiedJavaType type = new FullyQualifiedJavaType(
                introspectedTable.getMyBatis3JavaMapperType());

        String mapperName = type.getShortNameWithoutTypeArguments();
        String modelName = mapperName.substring(0, mapperName.length() - "Mapper".length());

        String tableNameAtRuntime = introspectedTable.getFullyQualifiedTableNameAtRuntime();


        TopLevelClass topLevelClass = new TopLevelClass("com.runfast.paotui.service.impl." + modelName + "ServiceImpl");
        topLevelClass.setVisibility(JavaVisibility.PUBLIC);
        topLevelClass.addAnnotation("@Service");
        commentGenerator.addJavaFileComment(topLevelClass);

        List<CompilationUnit> unitList = new ArrayList<CompilationUnit>();
        unitList.add(topLevelClass);


        FullyQualifiedJavaType baseServiceClass = new FullyQualifiedJavaType("com.runfast.common.service.BaseService");

        FullyQualifiedJavaType modelType = new FullyQualifiedJavaType(context.getJavaModelGeneratorConfiguration().getTargetPackage() + "." + modelName);
        topLevelClass.addImportedType(modelType);
        baseServiceClass.addTypeArgument(modelType);
        baseServiceClass.addTypeArgument(new FullyQualifiedJavaType("Integer"));

        FullyQualifiedJavaType exampleType = new FullyQualifiedJavaType(context.getJavaModelGeneratorConfiguration().getTargetPackage() + "." + modelName + "Example");
        topLevelClass.addImportedType(exampleType);
        baseServiceClass.addTypeArgument(exampleType);

//        FullyQualifiedJavaType mapperType = new FullyQualifiedJavaType(context.getJavaClientGeneratorConfiguration().getTargetPackage() + "." + modelName + "Mapper");
//        topLevelClass.addImportedType(mapperType);
//        baseServiceClass.addTypeArgument(mapperType);

        topLevelClass.setSuperClass(baseServiceClass);
        topLevelClass.addImportedType(new FullyQualifiedJavaType("com.runfast.common.service.BaseService"));

        FullyQualifiedJavaType iserviceClass = new FullyQualifiedJavaType("com.runfast.common.service.IService");

        iserviceClass.addTypeArgument(modelType);
        iserviceClass.addTypeArgument(new FullyQualifiedJavaType("Integer"));
        iserviceClass.addTypeArgument(exampleType);

        Interface anInterface = new Interface("com.runfast.paotui.service." + modelName + "Service");
        anInterface.setVisibility(JavaVisibility.PUBLIC);
        anInterface.addSuperInterface(iserviceClass);
        anInterface.addImportedType(new FullyQualifiedJavaType("com.runfast.common.service.IService"));
        anInterface.addImportedType(modelType);
        anInterface.addImportedType(exampleType);
        unitList.add(anInterface);

        FullyQualifiedJavaType interfaceType = anInterface.getType();

        topLevelClass.addSuperInterface(interfaceType);
        topLevelClass.addImportedType("org.springframework.stereotype.Service");
        topLevelClass.addImportedType("com.runfast.paotui.service." + modelName + "Service");


        List<CompilationUnit> compilationUnits = unitList;
        for (CompilationUnit compilationUnit : compilationUnits) {
            GeneratedJavaFile gjf = new GeneratedJavaFile(compilationUnit,
                    context.getJavaClientGeneratorConfiguration()
                            .getTargetProject(),
                    context.getProperty(PropertyRegistry.CONTEXT_JAVA_FILE_ENCODING),
                    context.getJavaFormatter());
            answer.add(gjf);
        }
        return answer;
    }

    @Override
    public List<GeneratedXmlFile> contextGenerateAdditionalXmlFiles() {
        return null;
    }

    @Override
    public List<GeneratedXmlFile> contextGenerateAdditionalXmlFiles(IntrospectedTable introspectedTable) {
        return null;
    }

    @Override
    public boolean clientGenerated(Interface interfaze, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        if (introspectedTable.getTargetRuntime() == IntrospectedTable.TargetRuntime.MYBATIS3) {
            String interfazeName = interfaze.getType().getShortNameWithoutTypeArguments();
            String modelName = interfazeName.substring(0, interfazeName.length() - "Mapper".length());

            FullyQualifiedJavaType superInterface = new FullyQualifiedJavaType("com.runfast.common.dao.IMapper");
            List<FullyQualifiedJavaType> typeArguments = superInterface.getTypeArguments();

            FullyQualifiedJavaType modelType = new FullyQualifiedJavaType(context.getJavaModelGeneratorConfiguration().getTargetPackage() + "." + modelName);
            interfaze.addImportedType(modelType);
            superInterface.addTypeArgument(modelType);
            superInterface.addTypeArgument(new FullyQualifiedJavaType("Integer"));

            FullyQualifiedJavaType exampleType = new FullyQualifiedJavaType(context.getJavaModelGeneratorConfiguration().getTargetPackage() + "." + modelName + "Example");
            interfaze.addImportedType(exampleType);
            superInterface.addTypeArgument(exampleType);

            interfaze.addSuperInterface(superInterface);

            interfaze.addImportedType(new FullyQualifiedJavaType("org.apache.ibatis.annotations.Mapper"));
            interfaze.addAnnotation("@Mapper");

            interfaze.addImportedType(new FullyQualifiedJavaType("com.runfast.common.dao.IMapper"));
        }

        return true;
    }

    @Override
    public boolean clientCountByExampleMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        return false;
    }

    @Override
    public boolean clientDeleteByExampleMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        return false;
    }

    @Override
    public boolean clientDeleteByPrimaryKeyMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        return false;
    }

    @Override
    public boolean clientInsertMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        return false;
    }

    @Override
    public boolean clientInsertSelectiveMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        return false;
    }

    @Override
    public boolean clientSelectByExampleWithBLOBsMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        return false;
    }

    @Override
    public boolean clientSelectByExampleWithoutBLOBsMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        return false;
    }

    @Override
    public boolean clientSelectByPrimaryKeyMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        return false;
    }

    @Override
    public boolean clientUpdateByExampleSelectiveMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        return false;
    }

    @Override
    public boolean clientUpdateByExampleWithBLOBsMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        return false;
    }

    @Override
    public boolean clientUpdateByExampleWithoutBLOBsMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        return false;
    }

    @Override
    public boolean clientUpdateByPrimaryKeySelectiveMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        return false;
    }

    @Override
    public boolean clientUpdateByPrimaryKeyWithBLOBsMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        return false;
    }

    @Override
    public boolean clientUpdateByPrimaryKeyWithoutBLOBsMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        return false;
    }

    @Override
    public boolean clientCountByExampleMethodGenerated(Method method, Interface interfaze, IntrospectedTable introspectedTable) {
        return false;
    }

    @Override
    public boolean clientDeleteByExampleMethodGenerated(Method method, Interface interfaze, IntrospectedTable introspectedTable) {
        return false;
    }

    @Override
    public boolean clientDeleteByPrimaryKeyMethodGenerated(Method method, Interface interfaze, IntrospectedTable introspectedTable) {
        return false;
    }

    @Override
    public boolean clientInsertMethodGenerated(Method method, Interface interfaze, IntrospectedTable introspectedTable) {
        return false;
    }

    @Override
    public boolean clientInsertSelectiveMethodGenerated(Method method, Interface interfaze, IntrospectedTable introspectedTable) {
        return false;
    }

    @Override
    public boolean clientSelectAllMethodGenerated(Method method, Interface interfaze, IntrospectedTable introspectedTable) {
        return false;
    }

    @Override
    public boolean clientSelectAllMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        return false;
    }

    @Override
    public boolean clientSelectByExampleWithBLOBsMethodGenerated(Method method, Interface interfaze, IntrospectedTable introspectedTable) {
        /*if (introspectedTable.getTargetRuntime() == IntrospectedTable.TargetRuntime.MYBATIS3) {
            copyAndAddMethod(method, interfaze);
        }*/
        return false;
    }

    @Override
    public boolean clientSelectByExampleWithoutBLOBsMethodGenerated(
            Method method, Interface interfaze,
            IntrospectedTable introspectedTable) {
        /*if (introspectedTable.getTargetRuntime() == IntrospectedTable.TargetRuntime.MYBATIS3) {
            copyAndAddMethod(method, interfaze);
        }*/
        return false;
    }

    @Override
    public boolean clientSelectByPrimaryKeyMethodGenerated(Method method, Interface interfaze, IntrospectedTable introspectedTable) {
        return false;
    }

    @Override
    public boolean clientUpdateByExampleSelectiveMethodGenerated(Method method, Interface interfaze, IntrospectedTable introspectedTable) {
        return false;
    }

    @Override
    public boolean clientUpdateByExampleWithBLOBsMethodGenerated(Method method, Interface interfaze, IntrospectedTable introspectedTable) {
        return false;
    }

    @Override
    public boolean clientUpdateByExampleWithoutBLOBsMethodGenerated(Method method, Interface interfaze, IntrospectedTable introspectedTable) {
        return false;
    }

    @Override
    public boolean clientUpdateByPrimaryKeySelectiveMethodGenerated(Method method, Interface interfaze, IntrospectedTable introspectedTable) {
        return false;
    }

    @Override
    public boolean clientUpdateByPrimaryKeyWithoutBLOBsMethodGenerated(Method method, Interface interfaze, IntrospectedTable introspectedTable) {
        return false;
    }

    @Override
    public boolean modelFieldGenerated(Field field, TopLevelClass topLevelClass, IntrospectedColumn introspectedColumn, IntrospectedTable introspectedTable, ModelClassType modelClassType) {
        return true;
    }

    @Override
    public boolean modelGetterMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedColumn introspectedColumn, IntrospectedTable introspectedTable, ModelClassType modelClassType) {
        return true;
    }

    @Override
    public boolean modelSetterMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedColumn introspectedColumn, IntrospectedTable introspectedTable, ModelClassType modelClassType) {
        return true;
    }

    @Override
    public boolean modelPrimaryKeyClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        return true;
    }

    @Override
    public boolean modelBaseRecordClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        return true;
    }

    @Override
    public boolean modelRecordWithBLOBsClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        return true;
    }

    @Override
    public boolean modelExampleClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        return true;
    }

    @Override
    public boolean sqlMapGenerated(GeneratedXmlFile sqlMap, IntrospectedTable introspectedTable) {
        return true;
    }

    @Override
    public boolean clientUpdateByPrimaryKeyWithBLOBsMethodGenerated(Method method, Interface interfaze, IntrospectedTable introspectedTable) {
        return false;
    }

    @Override
    public boolean sqlMapSelectByExampleWithoutBLOBsElementGenerated(
            XmlElement element, IntrospectedTable introspectedTable) {
        if (introspectedTable.getTargetRuntime() == IntrospectedTable.TargetRuntime.MYBATIS3) {
            XmlElement xmlElement = new XmlElement("");
            copyAndSaveElement(xmlElement, introspectedTable);
            new SelectByExampleWithPageableWithoutBLOBsElementGenerator(introspectedTable, context).addElements(xmlElement);
        }
        return true;
    }

    @Override
    public boolean sqlMapSelectByExampleWithBLOBsElementGenerated(
            XmlElement element, IntrospectedTable introspectedTable) {
        if (introspectedTable.getTargetRuntime() == IntrospectedTable.TargetRuntime.MYBATIS3) {
            XmlElement xmlElement = new XmlElement("");
            copyAndSaveElement(xmlElement, introspectedTable);
            new SelectByExampleWithPageableWithBLOBsElementGenerator(introspectedTable, context).addElements(xmlElement);
        }
        return true;
    }

    @Override
    public boolean sqlMapUpdateByExampleSelectiveElementGenerated(XmlElement element, IntrospectedTable introspectedTable) {
        return true;
    }

    @Override
    public boolean sqlMapUpdateByExampleWithBLOBsElementGenerated(XmlElement element, IntrospectedTable introspectedTable) {
        return true;
    }

    @Override
    public boolean sqlMapUpdateByExampleWithoutBLOBsElementGenerated(XmlElement element, IntrospectedTable introspectedTable) {
        return true;
    }

    @Override
    public boolean sqlMapUpdateByPrimaryKeySelectiveElementGenerated(XmlElement element, IntrospectedTable introspectedTable) {
        return true;
    }

    @Override
    public boolean sqlMapUpdateByPrimaryKeyWithBLOBsElementGenerated(XmlElement element, IntrospectedTable introspectedTable) {
        return true;
    }

    @Override
    public boolean sqlMapUpdateByPrimaryKeyWithoutBLOBsElementGenerated(XmlElement element, IntrospectedTable introspectedTable) {
        return true;
    }

    @Override
    public boolean providerGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        return false;
    }

    @Override
    public boolean providerApplyWhereMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        return false;
    }

    @Override
    public boolean providerCountByExampleMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        return false;
    }

    @Override
    public boolean providerDeleteByExampleMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        return false;
    }

    @Override
    public boolean providerInsertSelectiveMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        return false;
    }

    @Override
    public boolean providerSelectByExampleWithBLOBsMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        return false;
    }

    @Override
    public boolean providerSelectByExampleWithoutBLOBsMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        return false;
    }

    @Override
    public boolean providerUpdateByExampleSelectiveMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        return false;
    }

    @Override
    public boolean providerUpdateByExampleWithBLOBsMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        return false;
    }

    @Override
    public boolean providerUpdateByExampleWithoutBLOBsMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        return false;
    }

    @Override
    public boolean providerUpdateByPrimaryKeySelectiveMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        return false;
    }

    /**
     * We'll override this method and add any new elements generated by
     * previous calls
     */
    @Override
    public boolean sqlMapDocumentGenerated(Document document,
                                           IntrospectedTable introspectedTable) {
        List<XmlElement> elements = elementsToAdd.get(introspectedTable.getFullyQualifiedTable());
        if (elements != null) {
            for (XmlElement element : elements) {
                document.getRootElement().addElement(element);
            }
        }

        return true;
    }

    @Override
    public boolean sqlMapResultMapWithoutBLOBsElementGenerated(XmlElement element, IntrospectedTable introspectedTable) {
        return true;
    }

    @Override
    public boolean sqlMapCountByExampleElementGenerated(XmlElement element, IntrospectedTable introspectedTable) {
        if (introspectedTable.getTargetRuntime() == IntrospectedTable.TargetRuntime.MYBATIS3) {
            XmlElement xmlElement = new XmlElement("");
            copyAndSaveElement(xmlElement, introspectedTable);
            new CountByExampleWithPageableElementGenerator(introspectedTable, context).addElements(xmlElement);
        }
        return true;
    }

    @Override
    public boolean sqlMapDeleteByExampleElementGenerated(XmlElement element, IntrospectedTable introspectedTable) {
        return true;
    }

    @Override
    public boolean sqlMapDeleteByPrimaryKeyElementGenerated(XmlElement element, IntrospectedTable introspectedTable) {
        return true;
    }

    @Override
    public boolean sqlMapExampleWhereClauseElementGenerated(XmlElement element, IntrospectedTable introspectedTable) {
        return true;
    }

    @Override
    public boolean sqlMapBaseColumnListElementGenerated(XmlElement element, IntrospectedTable introspectedTable) {
        return true;
    }

    @Override
    public boolean sqlMapBlobColumnListElementGenerated(XmlElement element, IntrospectedTable introspectedTable) {
        return true;
    }

    @Override
    public boolean sqlMapInsertElementGenerated(XmlElement element, IntrospectedTable introspectedTable) {
        return true;
    }

    @Override
    public boolean sqlMapInsertSelectiveElementGenerated(XmlElement element, IntrospectedTable introspectedTable) {
        element.addAttribute(new Attribute("keyProperty", "id"));
        return true;
    }

    @Override
    public boolean sqlMapResultMapWithBLOBsElementGenerated(XmlElement element, IntrospectedTable introspectedTable) {
        return true;
    }

    @Override
    public boolean sqlMapSelectAllElementGenerated(XmlElement element, IntrospectedTable introspectedTable) {
        return true;
    }

    @Override
    public boolean sqlMapSelectByPrimaryKeyElementGenerated(XmlElement element, IntrospectedTable introspectedTable) {
        return true;
    }

    /**
     * Use the method copy constructor to create a new method, then
     * add the pageable parameter.
     *
   //  * @param fullyQualifiedTable
     * @param method
     */
    private void copyAndAddMethod(Method method, Interface interfaze) {
        List<Parameter> parameters = method.getParameters();
        for (Parameter parameter : parameters) {
            List<String> annotations = parameter.getAnnotations();
            if (annotations.size() == 0) {
                parameter.addAnnotation("@Param(\"" + parameter.getName() + "\")");
            } else {
                for (String annotation : annotations) {
                    if (!annotation.contains("@Param")) {
                        parameter.addAnnotation("@Param(\"" + parameter.getName() + "\")");
                    }
                }
            }

        }

        Method newMethod = new Method(method);
        newMethod.setName(method.getName() + "WithPageable"); //$NON-NLS-1$

        newMethod.addParameter(new Parameter(pageable, "pageable", "@Param(\"pageable\")")); //$NON-NLS-1$
        interfaze.addMethod(newMethod);
        interfaze.addImportedType(pageable);
        interfaze.addImportedType(new FullyQualifiedJavaType(
                "org.apache.ibatis.annotations.Param"));
    }

    /**
     * Use the method copy constructor to create a new element
     *
     //* @param fullyQualifiedTable
     //* @param method
     */
    /*private void copyAndSaveElement(XmlElement element, IntrospectedTable introspectedTable) {
        FullyQualifiedTable fqt = introspectedTable.getFullyQualifiedTable();
        XmlElement newElement = new XmlElement(element);

        // remove old id attribute and add a new one with the new name
        ArrayList<Attribute> attributesForRemove = new ArrayList<>();
        ArrayList<Attribute> attributesForadd = new ArrayList<>();
        List<Attribute> attributes = newElement.getAttributes();
        for (Iterator<Attribute> iterator = attributes.iterator(); iterator.hasNext(); ) {
            Attribute attribute = iterator.next();
            if ("id".equals(attribute.getName())) { //$NON-NLS-1$
//                iterator.remove();
                attributesForRemove.add(attribute);
                Attribute newAttribute = new Attribute("id", attribute.getValue() + "WithPageable"); //$NON-NLS-1$ //$NON-NLS-2$
                attributesForadd.add(newAttribute);
//                break;
            }

            if ("parameterType".equals(attribute.getName())) { //$NON-NLS-1$
                attributesForRemove.add(attribute);
                Attribute newAttribute = new Attribute("parameterType", "map"); //$NON-NLS-1$ //$NON-NLS-2$
                attributesForadd.add(newAttribute);
//                break;
            }

        }


        attributes.removeAll(attributesForRemove);
        attributes.addAll(attributesForadd);

        newElement.getElements().clear();

        newElement.addElement(new TextElement("select")); //$NON-NLS-1$
        XmlElement ifElement = new XmlElement("if"); //$NON-NLS-1$
        ifElement.addAttribute(new Attribute("test", "distinct")); //$NON-NLS-1$ //$NON-NLS-2$
        ifElement.addElement(new TextElement("distinct")); //$NON-NLS-1$
        newElement.addElement(ifElement);

        StringBuilder sb = new StringBuilder();
        if (stringHasValue(introspectedTable
                .getSelectByExampleQueryId())) {
            sb.append('\'');
            sb.append(introspectedTable.getSelectByExampleQueryId());
            sb.append("' as QUERYID,"); //$NON-NLS-1$
            newElement.addElement(new TextElement(sb.toString()));
        }

        XmlElement answer = new XmlElement("include"); //$NON-NLS-1$
        answer.addAttribute(new Attribute("refid", //$NON-NLS-1$
                introspectedTable.getBaseColumnListId()));
        newElement.addElement(answer);
        newElement.addElement(new TextElement(",")); //$NON-NLS-1$

        XmlElement answer1 = new XmlElement("include"); //$NON-NLS-1$
        answer1.addAttribute(new Attribute("refid", //$NON-NLS-1$
                introspectedTable.getBlobColumnListId()));
        newElement.addElement(answer1);

        sb.setLength(0);
        sb.append("from "); //$NON-NLS-1$
        sb.append(introspectedTable
                .getAliasedFullyQualifiedTableNameAtRuntime());
        newElement.addElement(new TextElement(sb.toString()));


        XmlElement ifParamElement = new XmlElement("if"); //$NON-NLS-1$
        ifParamElement.addAttribute(new Attribute("test", "example != null")); //$NON-NLS-1$ //$NON-NLS-2$

        XmlElement includeElement = new XmlElement("include"); //$NON-NLS-1$
        includeElement.addAttribute(new Attribute("refid", //$NON-NLS-1$
                introspectedTable.getMyBatis3UpdateByExampleWhereClauseId()));
        ifParamElement.addElement(includeElement);

        newElement.addElement(ifParamElement);

        XmlElement ifElement = new XmlElement("if"); //$NON-NLS-1$
        ifElement.addAttribute(new Attribute("test", "pageable != null")); //$NON-NLS-1$ //$NON-NLS-2$
        ifElement.addElement(new TextElement("limit ${pageable.offset},${pageable.pageSize}")); //$NON-NLS-1$
        newElement.addElement(ifElement);

        *//*List<Element> newElementElements = newElement.getElements();
        for (Element elementElement : newElementElements) {
            if (elementElement.getClass().isAssignableFrom(XmlElement.class)) {
                XmlElement xmlElement = (XmlElement) elementElement;
                List<Attribute> attributeList = xmlElement.getAttributes();
                for (Attribute attribute : attributeList) {
                    if ("_parameter != null".equals(attribute.getValue())) {

                        xmlElement.getElements().clear();

                        XmlElement includeElement = new XmlElement("include"); //$NON-NLS-1$
                        includeElement.addAttribute(new Attribute("refid", //$NON-NLS-1$
                                introspectedTable.getMyBatis3UpdateByExampleWhereClauseId()));
                        xmlElement.getElements().add(includeElement);
                    }
                }
            }

        }*//*



        // save the new element locally.   We'll add it to the document
        // later
        List<XmlElement> elements = elementsToAdd.get(fqt);
        if (elements == null) {
            elements = new ArrayList<XmlElement>();
            elementsToAdd.put(fqt, elements);
        }
        elements.add(newElement);
    }*/
    private void copyAndSaveElement(XmlElement element, IntrospectedTable introspectedTable) {


        FullyQualifiedTable fqt = introspectedTable.getFullyQualifiedTable();
        // save the new element locally.   We'll add it to the document
        // later
        List<XmlElement> elements = elementsToAdd.get(fqt);
        if (elements == null) {
            elements = new ArrayList<XmlElement>();
            elementsToAdd.put(fqt, elements);
        }
        elements.add(element);
    }
}
